package com.base.netlib.interceptor

import okhttp3.Interceptor
import okhttp3.Request
import okhttp3.Response
import java.io.InterruptedIOException

class RetryInterceptor internal constructor(var builder: Builder) : Interceptor {

    @Throws(Exception::class)
    override fun intercept(chain: Interceptor.Chain): Response {
        val request: Request = chain.request()
        var retryNum = 0
        var response = doRequest(chain, request, retryNum)
        while ((response == null || !response.isSuccessful) && retryNum <= builder.executionCount) {
            val nextInterval = builder.retryInterval
            try {
                Thread.sleep(nextInterval)
            } catch (e: InterruptedException) {
                Thread.currentThread().interrupt()
                throw InterruptedIOException()
            }
            retryNum++
            response?.close()
            // retry the request
            response = doRequest(chain, request, retryNum)
        }

        return response!!
    }

    private fun doRequest(chain: Interceptor.Chain, request: Request, curRetryNum: Int): Response? {
        try {
            return chain.proceed(request)
        } catch (e: Exception) {
            if (curRetryNum == builder.executionCount) {
                // 当前已是最后一次重试，抛出具体错误
                throw  e
            }
        }
        return null;
    }

    class Builder {
        var executionCount = 3   //最大重试次数
        var retryInterval: Long = 1000 //重试的间隔
        fun executionCount(executionCount: Int): Builder {
            this.executionCount = executionCount
            return this
        }

        fun retryInterval(retryInterval: Long): Builder {
            this.retryInterval = retryInterval
            return this
        }

        fun build(): RetryInterceptor {
            return RetryInterceptor(this)
        }
    }

}